package com.huitone.smspfm.socket.protocol.sgip.message.msgbody;

import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.bin.common.utils.ArrayUtils;
import com.bin.common.utils.StringUtils;
import com.huitone.smspfm.socket.protocol.sgip.constant.Constant;
import com.huitone.smspfm.socket.protocol.sgip.conversion.TransferConverter;

/**   
* @Title: Submit.java 
* @Package com.huitone.smspfm.socket.protocol.sgip.msgbody 
* @Description: TODO(用一句话描述该文件做什么) 
* @author ybliang   
* @date 2017年3月23日 上午11:05:16 
* @version V1.0   
*/
public class Submit implements IBody {
	
	/**
	 * @字节长度 21
	 * @数据类型 Text
	 * @DESC
	 * 	业务端编码
	 */
	private byte[] srvNode = new byte[21];
	
	/**
	 * @字节长度 10
	 * @数据类型 Text
	 * @DESC
	 * 	短信业务编码
	 */
	private byte[] serviceCode = new byte[10];
	
	/**
	 * @字节长度 21
	 * @数据类型 Text
	 * @DESC
	 * 	发送端口号
	 */
	private byte[] sendPort = new byte[21];
	
	/**
	 * @字节长度 1
	 * @数据类型 Integer
	 * @DESC
	 * 	状态报告标记
		0-该条消息只有最后出错时要返回状态报告
		1-该条消息无论最后是否成功都要返回状态报告
		2-该条消息不需要返回状态报告
		其它-保留
		缺省设置为0
	 */
	private byte[] reportFlag = new byte[1];
	
	/**
	 * @字节长度 1
	 * @数据类型 Integer
	 * @DESC
	 * 	接收短消息的手机数量，取值范围1至100
	 */
	private byte[] userCount = new byte[1];
	
	/**
	 * @字节长度 userCount * 13
	 * @数据类型 Text
	 * @DESC
	 * 	接收该短消息的手机号，该字段重复userCount指定的次数
	 */
	private byte[] userNumber;
	
	
	/**
	 * @字节长度 1
	 * @数据类型 Integer
	 * @DESC
	 * 	短消息的编码格式。
		0：纯ASCII字符串
		3：写卡操作
		4：二进制编码
		8：UCS2编码
		15: GBK编码
		其它参见GSM3.38第4节：SMS Data Coding Scheme
	 */
	private byte[] msgCoding = new byte[1];
	
	/**
	 * @字节长度 1
	 * @数据类型 Integer
	 * @DESC
	 * 	信息类型：
		0-短消息信息
		其它：待定
	 */
	private byte[] msgType = new byte[1];
	
	/**
	 * @字节长度 4
	 * @数据类型 Integer
	 * @DESC
	 * 	短消息的长度
	 */
	private byte[] msgLength = new byte[4];
	
	/**
	 * @字节长度 messageLength
	 * @数据类型 Text
	 * @DESC
	 * 	短消息的内容
	 */
	private byte[] msgContent;
	
	private byte[] submit = null;
	
	public static Submit build(byte[] bytes) throws ArrayIndexOutOfBoundsException {
		
		Submit submit = new Submit();
		
		int index = 0;
		
		submit.srvNode = ArrayUtils.subarray(bytes, index, index += 21);
		submit.serviceCode = ArrayUtils.subarray(bytes, index, index += 10);
		submit.sendPort = ArrayUtils.subarray(bytes, index, index += 21);
		submit.reportFlag = ArrayUtils.subarray(bytes, index, index += 1);
		submit.userCount = ArrayUtils.subarray(bytes, index, index += 1);
		submit.userNumber = ArrayUtils.subarray(bytes, index, index += (submit.getUserCount() * 13));
		submit.msgCoding = ArrayUtils.subarray(bytes, index, index += 1);
		submit.msgType = ArrayUtils.subarray(bytes, index, index += 1);
		submit.msgLength = ArrayUtils.subarray(bytes, index, index += 4);
		submit.msgContent = ArrayUtils.subarray(bytes, index, index += submit.getMsgLength());
		
		return submit;
	}
	
	public static Submit build(List<String> userNumbers, String srvNode, String serviceCode, String sendPort, int reportFlag, int msgCoding, int msgType, String msgContent) {
		
		Submit submit = new Submit();
		
		submit.setUserNumber(userNumbers);
		submit.setSrvNode(srvNode);
		submit.setServiceCode(serviceCode);
		submit.setSendPort(sendPort);
		submit.setReportFlag(reportFlag);
		submit.setMsgCoding(msgCoding);
		submit.setMsgType(msgType);
		submit.setMsgContent(msgContent);
		
		return submit;
	}
	
	@Override
	public byte[] toByteArray() {
		
		if (submit == null) {
			submit = ArrayUtils.addAll(srvNode, serviceCode, sendPort, reportFlag, userCount, userNumber, msgCoding, msgType, msgLength, msgContent);
		}
		
		return submit;
	}

	@Override
	public int length() {
		return toByteArray().length;
	}

	public String getSrvNode() {
		return TransferConverter.lj2Str(srvNode);
	}
	
	private void setSrvNode(String srvNode) {
		this.srvNode = TransferConverter.toLJ(this.srvNode, srvNode);
	}

	public String getServiceCode() {
		return TransferConverter.lj2Str(serviceCode);
	}

	private void setServiceCode(String serviceCode) {
		this.serviceCode = TransferConverter.toLJ(this.serviceCode, serviceCode);
	}

	public String getSendPort() {
		return TransferConverter.lj2Str(sendPort);
	}

	private void setSendPort(String sendPort) {
		this.sendPort = TransferConverter.toLJ(this.sendPort, sendPort);
	}

	public int getReportFlag() {
		return TransferConverter.bE2Int1(reportFlag);
	}

	private void setReportFlag(int reportFlag) {
		this.reportFlag = TransferConverter.toBE1(reportFlag);
	}

	public int getUserCount() {
		return TransferConverter.bE2Int1(userCount);
	}
	
	private void setUserCount(int userCount) {
		this.userCount = TransferConverter.toBE1(userCount);
	}

	public Set<String> getUserNumber() {
		
		Set<String> list = new HashSet<String>();
		
		int count = getUserCount();
		
		for (int i = 0 ; i < count ; i ++) { // 0 13 13 26 26 39
			list.add(TransferConverter.lj2Str(ArrayUtils.subarray(this.userNumber, i * 13, (i + 1) * 13)));
		}
		
		return list;
	}

	/**
	 * 超过Constant.maxUserCount以后的号码将被裁剪丢弃
	 * @param userNumber
	 */
	private void setUserNumber(List<String> userNumber) {
		
		if (userNumber != null) {
			int size = userNumber.size();
			int count = size > Constant.maxUserCount ? Constant.maxUserCount : size;
			for (int i = 0 ; i < count ; i ++) {
				this.userNumber = ArrayUtils.addAll(this.userNumber, TransferConverter.toLJ(new byte[13], StringUtils.phNumRem86(userNumber.get(i))));
			}
			this.setUserCount(count);
		}
		
		if (this.userNumber == null) {
			this.userNumber = new byte[]{};
			this.setUserCount(0);
		}
	}

	public int getMsgCoding() {
		return TransferConverter.bE2Int1(msgCoding);
	}

	private void setMsgCoding(int msgCoding) {
		this.msgCoding = TransferConverter.toBE1(msgCoding);
	}

	public int getMsgType() {
		return TransferConverter.bE2Int1(msgType);
	}

	private void setMsgType(int msgType) {
		this.msgType = TransferConverter.toBE1(msgType);
	}

	public int getMsgLength() {
		return TransferConverter.bE2Int4(msgLength);
	}

	private void setMsgLength(int msgLength) {
		this.msgLength = TransferConverter.toBE4(msgLength);
	}

	public String getMsgContent() {
		
		String result = null;
		
		try {
			result = new String(this.msgContent, Constant.MessageCodingP.parse(getMsgCoding()));
			result = StringUtils.removeNonChar(result);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		return result;
	}

	private void setMsgContent(String msgContent) {
		msgContent = StringUtils.removeNonChar(msgContent);
		if (!StringUtils.isEmpty(msgContent)) {
			
			try {
				byte[] bytes = msgContent.getBytes(Constant.MessageCodingP.parse(getMsgCoding()));
				setMsgLength(bytes.length);
				this.msgContent = bytes;
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		} else {
			this.msgContent = new byte[]{};
			setMsgLength(0);
		}
	}

	@Override
	public String toString() {
		return "Submit [业务端号=" + getSrvNode() + ", 业务类型=" + getServiceCode() + ", 扩展码="
				+ getSendPort() + ", 报告标识=" + getReportFlag()
				+ ", 用户号码=" + getUserNumber() + ", 短信编码=" + getMsgCoding() + ", 短信类型="
				+ getMsgType() + ", 短信内容=" + getMsgContent() + "]";
	}

	@Override
	public String toSimpleString() {
		return getUserNumber() + " " + getSrvNode() + " " + getServiceCode() + " " + getSendPort() + " " + getReportFlag();
	}
}
